package com.chushouya.order.service.admin.impl;

import com.general.framework.core.lang.*;
import com.chushouya.common.applet.WxClient;
import com.chushouya.common.config.WxClerkLiteConfig;
import com.chushouya.common.config.WxOfficialConfig;
import com.chushouya.common.support.DevOption;
import com.chushouya.common.wx.dto.WxMessagePushRequest;
import com.general.framework.core.exception.Ex;
import com.chushouya.manager.config.BizConfigEnum;
import com.chushouya.manager.dao.entity.UserExtendEntity;
import com.chushouya.manager.dao.repository.UserExtendRepository;
import com.chushouya.manager.dto.admin.clerk.ClerkInfoDTO;
import com.chushouya.manager.dto.admin.sms.SmsDTO;
import com.chushouya.manager.service.api.ClerkApiService;
import com.chushouya.manager.service.common.ConfigApiService;
import com.chushouya.manager.service.common.SmsService;
import com.chushouya.order.constants.LogisticsTypeEnum;
import com.chushouya.order.constants.OrderStatusEnum;
import com.chushouya.order.constants.OrderTypeEnum;
import com.chushouya.order.dao.entity.OrderAddressEntity;
import com.chushouya.order.dao.entity.OrderEntity;
import com.chushouya.order.dao.entity.OrderLogisticsEntity;
import com.chushouya.order.dao.repository.OrderAddressRepository;
import com.chushouya.order.dao.repository.OrderLogisticsRepository;
import com.chushouya.order.dao.repository.OrderRepository;
import com.chushouya.order.dto.admin.orderlogistics.OrderLogisticsQuery;
import com.chushouya.order.dto.admin.smsscene.SmsSceneDTO;
import com.chushouya.order.service.admin.OrderNotifyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;


@Slf4j
@Service
public class OrderNotifyServiceImpl implements OrderNotifyService {

    @Resource
    private OrderAddressRepository orderAddressRepository;

    @Resource
    private OrderRepository orderRepository;

    @Resource
    private OrderLogisticsRepository orderLogisticsRepository;

    @Resource
    private UserExtendRepository userExtendRepository;

    @Resource
    private WxOfficialConfig wxOfficialConfig;

    @Resource
    private WxClerkLiteConfig wxClerkLiteConfig;

    @Resource
    private ClerkApiService clerkApiService;

    @Resource
    private ConfigApiService configApiService;

    @Resource
    private SmsService smsService;

    private OrderEntity getOrder(Long orderId) {
        OrderEntity orderEntity = orderRepository.selectByPrimaryKey(orderId);
        Validate.isNull(orderEntity, "订单不存在");
        return orderEntity;
    }

    /**
     * 聚合通知
     */
    @Override
    public void orderStatusNotify(Long orderId) {
//        if (DevOption.isDevModel()) {
//            log.info("开发环境不同步数据");
//            return;
//        }
        OrderEntity orderEntity = this.getOrder(orderId);
        final String partnerOrderNo = orderEntity.getPartnerOrderNo();
        final String orderNo = orderEntity.getOrderNo();
//        if (Strings.isNotEmpty(partnerOrderNo)){
//            log.info("订单号:{} 合作订单号:{} 不同步订单状态", orderNo, partnerOrderNo);
//            return;
//        }
//        try {
//            //支付宝同步
////            alipayOrderSyncService.syncAlipayOrder(orderId, "", bizType);
//        } catch (ViolationException e) {
//            log.info("同步支付宝订单异常：{},{}", orderId, e.getMessage());
//        } catch (Exception e) {
//            log.error("消息队列执行异常:{}", orderId, e);
//        }

        //短信通知
        sendSmsToUser(orderEntity);


    }

    /**
     * 发送用户微信通知
     */
    private void sendWechatToUser(OrderEntity orderEntity) {
    }

    /**
     * 业务员发送微信消息
     */
    @Override
    public void sendWechatToClerk(Long orderId) {
        if (DevOption.isDevModel()) {
            log.info("开发环境不发送微信消息");
//            return;
        }
        OrderEntity orderEntity = this.getOrder(orderId);
        final Long clerkId =  orderEntity.getClerkId();
        final String clerkName =  orderEntity.getClerkName();
        final String orderNo =  orderEntity.getOrderNo();
        final String userName =  orderEntity.getUserName();
        final String userPhone =  orderEntity.getUserPhone();
        final Date appointStartTime =  orderEntity.getAppointStartTime();
        ClerkInfoDTO clerkInfoDTO = clerkApiService.getClerkInfo(clerkId);
        Validate.isNull(clerkInfoDTO, "业务员信息不存在");
        final Long userId = clerkInfoDTO.getUserId();
        UserExtendEntity clerkExtendEntity = userExtendRepository.selectByAppIdAndUserId(wxOfficialConfig.getAppId(),userId);
        if (Objects.isNull(clerkExtendEntity)) {
            throw Ex.business("业务员微信信息不存在");
        }

        OrderAddressEntity orderAddressEntity = orderAddressRepository.selectByOrderId(orderId);
        Validate.isNull(orderAddressEntity, "订单地址不存在");



        String openId = clerkExtendEntity.getOpenId();
        final String templateId = "BsVUmDYOeSj_sanDLHwDYnNa7354fqxQUnHS6gxglqg";
        //发送微信模板消息
        WxMessagePushRequest wxMessagePushRequest = new WxMessagePushRequest();
        wxMessagePushRequest.setOpenId(openId);
        wxMessagePushRequest.setTemplateId(templateId);
        if(!DevOption.isDevModel()){
            String path = Strings.format("{}{}", "pages/order/detail/index?orderId=", orderId);
            wxMessagePushRequest.setLiteAppId(wxClerkLiteConfig.getAppId());
            wxMessagePushRequest.setLiteLinkPage(path);
        }
        Map<String, WxMessagePushRequest.Value> data = new HashMap<>();
        final String address = orderAddressEntity.getAddress();
        Integer addressLength = address.length() > 20 ? 20 : address.length();

        data.put("const1", new WxMessagePushRequest.Value("手机"));
        data.put("thing5", new WxMessagePushRequest.Value(userName));
        data.put("phone_number6", new WxMessagePushRequest.Value(userPhone));
        data.put("thing3", new WxMessagePushRequest.Value(orderAddressEntity.getAddress().substring(0, addressLength)));
        data.put("time2", new WxMessagePushRequest.Value(Dates.format(appointStartTime, Dates.FMT_FULL_TIME)));
        wxMessagePushRequest.setData(data);
        WxClient client = new WxClient(wxOfficialConfig.getAppId(), wxOfficialConfig.getAppSecret());
        try {
            log.info("发送微信消息:业务员:{} 订单号:{} 数据:{}", clerkName, orderNo, Jsons.toJsonString(wxMessagePushRequest));
            client.sendOfficialTemplateMessage(wxMessagePushRequest);
        } catch (Exception e) {
            log.error("发送微信消息失败:{} {} {}", clerkName, Jsons.toJsonString(wxMessagePushRequest), e.getMessage());

        }
    }

    /**
     * 给业务员发送信息
     */
    @Override
    public void sendSmsToClerk(Long orderId) {
        if (DevOption.isDevModel()) {
            log.info("开发环境不发送短信");
            return;
        }
        log.info("给业务员发送短信:订单ID:{}", orderId);
        OrderEntity orderEntity = this.getOrder(orderId);
        final Long clerkId =  orderEntity.getClerkId();
        final Integer orderStatus =  orderEntity.getOrderStatus();
        final Integer orderType =  orderEntity.getOrderType();
        final String orderNo =  orderEntity.getOrderNo();
        final String userPhone =  orderEntity.getUserPhone();
        if (!Objects.equals(orderType, OrderTypeEnum.DOOR_RECYCLE.value()) && Longs.isNullOrZero(clerkId)) {
            log.info("非上门回收订单不发送业务员短信:订单ID:{}", orderId);
            return;
        }
        ClerkInfoDTO clerkInfoDTO = clerkApiService.getClerkInfo(clerkId);
        Validate.isNull(clerkInfoDTO, "业务员信息不存在");
        final String smsClerkSceneJson = configApiService.getStringConfig(BizConfigEnum.SMS_CLERK_SCENE.getConfigKey());

        List<SmsSceneDTO> smsSceneList = Jsons.parseArray(smsClerkSceneJson, SmsSceneDTO.class);
        String templateCode = "";
        for (SmsSceneDTO smsSceneDto : smsSceneList) {
            if (smsSceneDto.getOrderStatus().equals(orderStatus.toString())) {
                templateCode = smsSceneDto.getSmsTemplateCode();
                break;
            }
        }
        Validate.isNull(templateCode, "业务员场景短信不存在");
        //业务员手机号
        String phone = clerkInfoDTO.getClerkPhone();
        Map<String, String> params = new HashMap<>();
        params.put("ORDERNO", orderNo);
        params.put("TEL", userPhone);
        SmsDTO smsDTO = new SmsDTO();
        smsDTO.setPhone(phone);
        smsDTO.setParams(params);
        smsDTO.setTemplateCode(templateCode);
        smsService.sendDynamicTemplateSms(smsDTO);

    }


    /**
     * 用户短信通知
     */
    private void sendSmsToUser(OrderEntity orderEntity) {
        if (DevOption.isDevModel()) {
            log.info("开发环境不发送短信");
//            return;
        }
        log.info("给用户发送短信:订单ID:{}", orderEntity.getOrderId());
        final Integer orderStatus =  orderEntity.getOrderStatus();
        final Integer orderType =  orderEntity.getOrderType();
        final String userPhone =  orderEntity.getUserPhone();
        final String smsClerkSceneJson = configApiService.getStringConfig(BizConfigEnum.SMS_SCENE.getConfigKey());
        String sceneStatus = Strings.format("{}", orderStatus);
        if (Objects.equals(orderStatus, OrderStatusEnum.NEW_ORDER.value())) {
            sceneStatus = Strings.format("{}{}", orderStatus, orderType);
        } else if (Objects.equals(orderStatus, OrderStatusEnum.WAIT_PAY.value())) {
            sceneStatus = Strings.format("{}{}", orderStatus, orderType);
        }
        List<SmsSceneDTO> smsSceneList = Jsons.parseArray(smsClerkSceneJson, SmsSceneDTO.class);

        //根据订单状态获取短信模板
        String smsSceneStatus = sceneStatus;
        String templateCode = null;
        try {
            Optional<SmsSceneDTO> first = smsSceneList.stream().filter(smsSceneDto -> smsSceneDto.getOrderStatus().equals(smsSceneStatus)).findFirst();
            if (first.isPresent()) {
                templateCode = first.get().getSmsTemplateCode();
            }
        } catch (Exception e) {
            log.error("短信场景配置错误:{}", sceneStatus);
        }

        Validate.isNull(templateCode, "此节点无短信");

        SmsDTO smsDTO = new SmsDTO();
        smsDTO.setPhone(userPhone);
        smsDTO.setTemplateCode(templateCode);
        handleSmsParams( orderEntity, smsDTO);
        smsService.sendDynamicTemplateSms(smsDTO);
    }

    /**
     * 短信带参数处理
     */
    private void handleSmsParams(OrderEntity orderEntity, SmsDTO smsDTO) {
        final Long clerkId =  orderEntity.getClerkId();
        final Integer orderStatus =  orderEntity.getOrderStatus();
        if (Objects.equals(orderStatus, OrderStatusEnum.WAIT_ACCEPT.value())) {
            //获取业务员信息
            ClerkInfoDTO clerkInfoRpcDTO = clerkApiService.getClerkInfo(clerkId);
            Validate.isNull(clerkInfoRpcDTO, "业务员信息不存在");
            Map<String, String> params = new HashMap<>();
            params.put("CLERKNAME", clerkInfoRpcDTO.getClerkName());
            params.put("CLERKPHONE", clerkInfoRpcDTO.getClerkPhone());
            smsDTO.setParams(params);
        }else if(Objects.equals(orderStatus, OrderStatusEnum.NEW_ORDER.value())) {
            String expressNo = getExpressNo( orderEntity.getOrderId());
            if (Strings.isEmpty(expressNo)) {
                return;
            }
            Map<String, String> params = new HashMap<>();
            params.put("productName",  orderEntity.getProductName());
            params.put("partnerOrderNo",  orderEntity.getPartnerOrderNo());
            params.put("expressNo", expressNo);
            params.put("time", Dates.format( orderEntity.getAppointStartTime(), Dates.FMT_FULL_TIME));
            smsDTO.setParams(params);
        }
    }


    /**
     * 获取订单快递单号
     * @param orderId
     */
    private String getExpressNo(Long orderId) {
        OrderLogisticsQuery query = new OrderLogisticsQuery();
        query.setOrderId(orderId);
        query.setType(LogisticsTypeEnum.USER_SEND.value());
        OrderLogisticsEntity orderLogisticsEntity = orderLogisticsRepository.selectOne(query);
        if (Objects.isNull(orderLogisticsEntity)) {
            return Strings.EMPTY;
        }
        return orderLogisticsEntity.getExpressNo();
    }

}
